package com.getpebble.android.framework.notification;

import android.content.ContentResolver;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import com.getpebble.android.PebbleApplication;
import com.getpebble.android.common.core.trace.Analytics.MobileAppBehavior;
import com.getpebble.android.common.core.trace.Trace;
import com.getpebble.android.common.core.util.PblPreferences;
import com.getpebble.android.common.core.util.PblPreferences.PrefKey;
import com.getpebble.android.common.model.PblAndroidAppModel;
import com.getpebble.android.common.model.PblAndroidAppModel.Record;
import com.getpebble.android.common.model.PblDevice;
import com.getpebble.android.common.model.PblNotificationModel;
import com.getpebble.android.framework.comm.MessageRouter;
import com.getpebble.android.framework.endpoint.NotificationEndpoint.INotificationCallback;
import com.getpebble.android.framework.endpoint.NotificationEndpoint.NotificationEndpointRequest;
import com.getpebble.android.framework.endpoint.NotificationEndpoint.RequestResult;
import com.getpebble.android.framework.notification.gmail.GmailCheckerService.ActionCallback;
import com.getpebble.android.notifications.model.Actions.PblNotificationAction;
import com.getpebble.android.notifications.model.Actions.PblNotificationAndroidAction;
import com.getpebble.android.notifications.model.Actions.PblNotificationDismissAction;
import com.getpebble.android.notifications.model.Actions.PblNotificationGmailAction;
import com.getpebble.android.notifications.model.Actions.PblNotificationOpenOnPhoneAction;
import com.getpebble.android.notifications.model.Actions.PblNotificationReplyAction;
import com.getpebble.android.notifications.model.PblNotification;
import com.getpebble.android.notifications.model.PblNotification.NotificationContent;
import com.getpebble.android.notifications.util.CoreNotifications;
import com.getpebble.android.notifications.util.NotificationUtil;
import com.google.common.primitives.UnsignedInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PblNotificationProcessor {
    private static final String TAG = PblNotificationProcessor.class.getSimpleName();
    private static PblNotificationProcessor sInstance = null;
    private final ContentResolver mContentResolver;
    private final Map<GroupKey, GroupMeta> mGroupProcessingMap = new HashMap();
    private final Handler mHandler = new Handler(Looper.getMainLooper());
    private Map<UnsignedInteger, List<PblNotificationAction>> mNotificationActions = new HashMap();
    private final PblPreferences mPblPreferences;

    private static class GroupKey {
        String groupKey;
        String pkg;

        private GroupKey() {
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            GroupKey groupKey1 = (GroupKey) o;
            if (this.groupKey == null ? groupKey1.groupKey != null : !this.groupKey.equals(groupKey1.groupKey)) {
                return false;
            }
            if (this.pkg != null) {
                if (this.pkg.equals(groupKey1.pkg)) {
                    return true;
                }
            } else if (groupKey1.pkg == null) {
                return true;
            }
            return false;
        }

        public int hashCode() {
            int result;
            int i = 0;
            if (this.pkg != null) {
                result = this.pkg.hashCode();
            } else {
                result = 0;
            }
            int i2 = result * 31;
            if (this.groupKey != null) {
                i = this.groupKey.hashCode();
            }
            return i2 + i;
        }

        static GroupKey from(PblNotification notification) {
            GroupKey key = new GroupKey();
            key.groupKey = notification.getGroupKey();
            key.pkg = notification.getPackageName();
            return key;
        }
    }

    private static class GroupMeta {
        GroupKey key;
        List<PblNotification> notifications;
        Runnable runnable;

        private GroupMeta() {
        }
    }

    public enum InvokeActionResult {
        FAILED,
        DEFAULT_ACTION,
        DISMISSED,
        OPENED_ON_PHONE,
        REPLIED
    }

    public PblNotificationProcessor(Context context, PblPreferences preferences, ContentResolver contentResolver) {
        this.mPblPreferences = preferences;
        this.mContentResolver = contentResolver;
        PblNotificationModel.purgeNotificationsForAllPackages(this.mContentResolver);
        sInstance = this;
        verifyService();
    }

    protected void verifyService() {
        NotificationUtil.verifyService(PebbleApplication.getAppContext());
    }

    public static void processNotification(PblNotification pblNotification) {
        PblNotificationProcessor instance = sInstance;
        if (instance != null) {
            instance.onNotificationPosted(pblNotification);
        }
    }

    private synchronized void storeGroupNotification(PblNotification notification) {
        Trace.verbose(TAG, "storeGroupNotification pkg = " + notification.getPackageName() + " key = " + notification.getGroupKey());
        final GroupKey key = GroupKey.from(notification);
        GroupMeta meta = (GroupMeta) this.mGroupProcessingMap.get(key);
        if (meta == null) {
            Trace.verbose(TAG, "... is first for group");
            meta = new GroupMeta();
            meta.key = key;
            meta.notifications = new ArrayList();
            meta.runnable = new Runnable() {
                public void run() {
                    synchronized (PblNotificationProcessor.this) {
                        GroupMeta metaLookup = (GroupMeta) PblNotificationProcessor.this.mGroupProcessingMap.get(key);
                        if (metaLookup == null) {
                            Trace.warning(PblNotificationProcessor.TAG, "Processing GroupMeta for pkg = " + key.pkg + " key = " + key.groupKey + " - no metaLookup so not processing");
                            return;
                        }
                        Trace.debug(PblNotificationProcessor.TAG, "Processing GroupMeta for pkg = " + key.pkg + " key = " + key.groupKey);
                        for (PblNotification notif : metaLookup.notifications) {
                            PblNotificationProcessor.this.displayNotification(notif);
                        }
                        PblNotificationProcessor.this.mGroupProcessingMap.remove(key);
                    }
                }
            };
            this.mGroupProcessingMap.put(key, meta);
        }
        meta.notifications.add(notification);
        this.mHandler.removeCallbacks(meta.runnable);
        this.mHandler.postDelayed(meta.runnable, 750);
    }

    protected void sendAnalytics(PblNotification pblNotification, boolean sentToWatch) {
        NotificationUtil.sendNotificationAnalytics(pblNotification, sentToWatch);
    }

    protected boolean isChosen(String pkg) {
        boolean defaultToggleState = CoreNotifications.getDefaultToggleState(pkg);
        Record appRecord = PblAndroidAppModel.getAppRecord(pkg, this.mContentResolver);
        if (appRecord != null) {
            return appRecord.chosen;
        }
        return defaultToggleState;
    }

    private static boolean couldBeEnhancedByWearApp(String pkg) {
        if ("com.google.android.talk".equals(pkg) || "com.google.android.apps.inbox".equals(pkg)) {
            return true;
        }
        return false;
    }

    synchronized void onNotificationPosted(PblNotification pblNotification) {
        if (pblNotification == null) {
            throw new IllegalArgumentException("'notification' cannot be null!");
        }
        Trace.debug(TAG, "New notification from: " + pblNotification.getPackageName());
        NotificationUtil.dumpNotification(pblNotification);
        if (pblNotification.isOngoing()) {
            Trace.debug(TAG, "not processing ongoing notification");
        } else if (isChosen(pblNotification.getPackageName()) || pblNotification.isLegacyNotification()) {
            if (couldBeEnhancedByWearApp(pblNotification.getPackageName()) && !this.mPblPreferences.getBooleanData(PrefKey.RECEIVED_POTENTIAL_WEAR_ENHANCED_NOTIFICATION, false)) {
                this.mPblPreferences.setBooleanData(PrefKey.RECEIVED_POTENTIAL_WEAR_ENHANCED_NOTIFICATION, true);
            }
            if (!NotificationUtil.supportsSidechannel() || pblNotification.getGroupKey() == null) {
                displayNotification(pblNotification);
            } else {
                storeGroupNotification(pblNotification);
            }
        } else {
            Trace.debug(TAG, "Notification package not selected by user; skipping");
            sendAnalytics(pblNotification, false);
        }
    }

    private boolean shouldDisplayGroupSummaryNotification(PblNotification notification, GroupMeta groupMeta) {
        boolean doGroupProcessing = false;
        if ("com.whatsapp".equals(notification.getPackageName())) {
            doGroupProcessing = true;
        } else if ("com.google.android.apps.inbox".equals(notification.getPackageName())) {
            doGroupProcessing = true;
        } else if ("com.groupme.android".equals(notification.getPackageName())) {
            doGroupProcessing = true;
        } else if ("com.google.android.talk".equals(notification.getPackageName())) {
            List<PblNotificationAction> replyActions = notification.getOtherActions();
            if (replyActions == null || replyActions.isEmpty()) {
                doGroupProcessing = true;
            }
        }
        if (!doGroupProcessing) {
            return false;
        }
        boolean foundSideChannel = false;
        for (PblNotification otherNotif : groupMeta.notifications) {
            if (!otherNotif.isGroupSummary()) {
                foundSideChannel = true;
            }
        }
        if (foundSideChannel) {
            return false;
        }
        return true;
    }

    private PblNotification processSidechannelActionsFromGroupSummary(PblNotification notification, GroupMeta groupMeta) {
        for (PblNotification pblNotification : groupMeta.notifications) {
            if (pblNotification.isGroupSummary()) {
                Trace.verbose(TAG, "Adding actions from group summary to sidechannel");
                List<PblNotificationAction> summaryActions = pblNotification.getActions();
                if (summaryActions == null) {
                    return pblNotification;
                }
                for (PblNotificationAction action : summaryActions) {
                    if (action instanceof PblNotificationDismissAction) {
                        notification.setDismissAction((PblNotificationDismissAction) action);
                    } else {
                        notification.addActionIfNotPresent(action);
                    }
                }
                return pblNotification;
            }
        }
        return null;
    }

    private synchronized void displayNotification(final PblNotification pblNotification) {
        String groupSummaryKey = null;
        if (NotificationUtil.supportsSidechannel() && pblNotification.getGroupKey() != null) {
            GroupMeta groupMeta = (GroupMeta) this.mGroupProcessingMap.get(GroupKey.from(pblNotification));
            if (groupMeta == null) {
                Trace.warning(TAG, "No GroupMeta stored for groupKey notification >= 4.3. This is not expected");
            } else if (!pblNotification.isGroupSummary()) {
                PblNotification groupSummaryNotif = processSidechannelActionsFromGroupSummary(pblNotification, groupMeta);
                if (groupSummaryNotif != null) {
                    groupSummaryKey = groupSummaryNotif.getAndroidNotificationKey();
                }
            } else if (!shouldDisplayGroupSummaryNotification(pblNotification, groupMeta)) {
                Trace.debug(TAG, "Notification is group summary; ignoring");
                sendAnalytics(pblNotification, false);
            }
        }
        pblNotification.extractContent(groupSummaryKey);
        if (pblNotification.isDuplicate()) {
            Trace.debug(TAG, "Notification is duplicate; skipping");
            sendAnalytics(pblNotification, false);
        } else {
            final NotificationContent content = pblNotification.getNotificationContent();
            if (content == null || content.notificationTitle == null || content.notificationBody == null) {
                Trace.debug(TAG, "Notification has null title/body or is null");
                sendAnalytics(pblNotification, false);
            } else {
                final UnsignedInteger notificationId = getAndIncrementNotificationId(this.mPblPreferences);
                INotificationCallback callback = new INotificationCallback() {
                    public void notificationResult(RequestResult result) {
                        boolean isSent = !RequestResult.FAILED.equals(result);
                        boolean sentUsingExtensibleProtocol = RequestResult.SENT_EXTENSIBLE.equals(result);
                        Trace.debug(PblNotificationProcessor.TAG, "notificationResult() id = " + notificationId + " isSent = " + isSent + " sentUsingExtensibleProtocol = " + sentUsingExtensibleProtocol);
                        if (isSent) {
                            if (!pblNotification.isLegacyNotification()) {
                                PblNotificationModel.insert(PblNotificationProcessor.this.mContentResolver, new PblNotificationModel.Record(notificationId, pblNotification.getPackageName(), pblNotification.getAndroidNotificationId(), pblNotification.getAndroidNotificationTag(), pblNotification.getAndroidNotificationKey(), content.rawNotificationBody, pblNotification.getGroupKey(), pblNotification.isGroupSummary(), pblNotification.getPostTimeUtcMillis(), 0));
                            }
                            if (sentUsingExtensibleProtocol && pblNotification.isActionable()) {
                                PblNotificationProcessor.this.mNotificationActions.put(notificationId, pblNotification.getActions());
                            }
                        }
                    }
                };
                sendAnalytics(pblNotification, true);
                sendNotificationToWatch(pblNotification, notificationId, callback);
            }
        }
    }

    protected void sendNotificationToWatch(PblNotification notification, UnsignedInteger notificationId, INotificationCallback callback) {
        NotificationEndpointRequest request = NotificationEndpointRequest.getAddNotificationRequest(notification, notificationId, callback);
        PblDevice connectedDevice = PebbleApplication.getConnectedDevice();
        if (connectedDevice == null) {
            Trace.debug(TAG, "No connected device");
            return;
        }
        MessageRouter router = MessageRouter.getRouter(connectedDevice);
        if (router == null) {
            Trace.debug(TAG, "router is null");
            return;
        }
        router.onRequest(request, null);
        Trace.debug(TAG, "Notification request sent.");
    }

    public void reassignActions(UnsignedInteger oldId, UnsignedInteger newId) {
        List<PblNotificationAction> actions = (List) this.mNotificationActions.get(oldId);
        if (actions != null) {
            this.mNotificationActions.remove(oldId);
            this.mNotificationActions.put(newId, actions);
        }
    }

    public static void processNotificationRemoval(int id, String tag, String packageName, String key) {
        PblNotificationProcessor instance = sInstance;
        if (instance != null) {
            instance.onNotificationRemoved(id, tag, packageName, key);
        }
    }

    public static void processNotificationRemoval(String packageName) {
        PblNotificationProcessor instance = sInstance;
        if (instance != null) {
            instance.onNotificationRemoved(packageName);
        }
    }

    void onNotificationRemoved(int id, String tag, String packageName, String key) {
        String keyUse = key;
        if (keyUse == null) {
            keyUse = PblNotification.generateNotificationKey(packageName, id, tag);
        }
        Trace.debug(TAG, String.format("Removing notification with id=<%s> tag=<%s> package=<%s> key=<%s>", new Object[]{String.valueOf(id), tag, packageName, keyUse}));
        onNotificationRemoved(PblNotificationModel.findNotification(packageName, id, tag, keyUse, this.mContentResolver));
    }

    private void onNotificationRemoved(String packageName) {
        Trace.debug(TAG, String.format("Removing notification with package=<%s>", new Object[]{packageName}));
        List<PblNotificationModel.Record> records = PblNotificationModel.findNotifications(packageName, this.mContentResolver);
        if (records == null) {
            Trace.info(TAG, "records is null");
            return;
        }
        for (PblNotificationModel.Record record : records) {
            onNotificationRemoved(record);
        }
    }

    private void onNotificationRemoved(PblNotificationModel.Record notification) {
        if (notification == null) {
            Trace.warning(TAG, "Could not find matching notification");
            return;
        }
        this.mNotificationActions.remove(notification.notificationId);
        PblNotificationModel.markRemovedNotificationsForKey(PebbleApplication.getAppContext().getContentResolver(), notification.androidPackageName, notification.androidNotificationKey);
        NotificationEndpointRequest request = NotificationEndpointRequest.getRemoveNotificationRequest(notification.notificationId);
        for (MessageRouter router : MessageRouter.getAllRouters()) {
            router.onRequest(request, null);
        }
    }

    public static void processServiceCreate() {
        PblNotificationProcessor instance = sInstance;
    }

    public void destroy() {
        sInstance = null;
    }

    private static synchronized UnsignedInteger getAndIncrementNotificationId(PblPreferences preferences) {
        UnsignedInteger unsignedInteger;
        synchronized (PblNotificationProcessor.class) {
            long id = preferences.getLongData(PrefKey.NOTIFICATION_ID_SEQUENCE, -1);
            if (id == -1) {
                Trace.warning(TAG, "Failed to retrieve valid notification ID; resetting");
                id = 0;
            }
            unsignedInteger = UnsignedInteger.valueOf(id);
            preferences.setLongData(PrefKey.NOTIFICATION_ID_SEQUENCE, unsignedInteger.longValue() + 1);
        }
        return unsignedInteger;
    }

    public static synchronized void setLastNotificationId(UnsignedInteger newId, PblPreferences preferences) {
        synchronized (PblNotificationProcessor.class) {
            if (newId.longValue() > preferences.getLongData(PrefKey.NOTIFICATION_ID_SEQUENCE, -1)) {
                Trace.debug(TAG, "setLastNotificationId: updating for newId = " + newId);
                preferences.setLongData(PrefKey.NOTIFICATION_ID_SEQUENCE, newId.longValue() + 1);
            }
        }
    }

    public static PblNotificationProcessor getInstance() {
        return sInstance;
    }

    public void invokeAction(UnsignedInteger notificationId, int actionId, Map<Integer, String> attributes, Context context, ActionCallback callback) {
        List<PblNotificationAction> actions = (List) this.mNotificationActions.get(notificationId);
        if (actions == null) {
            Trace.debug(TAG, "Actions not found for notification ID: " + notificationId);
            callback.result(InvokeActionResult.FAILED);
            return;
        }
        PblNotificationModel.Record notification = PblNotificationModel.findNotification(notificationId, context.getContentResolver());
        callback.setNotificationRecord(notification);
        PblNotificationAction foundAction = null;
        for (PblNotificationAction action : actions) {
            if (action.getId() == actionId) {
                foundAction = action;
                break;
            }
        }
        if (foundAction == null) {
            Trace.debug(TAG, "invokeAction: action not found for ID: " + actionId);
            callback.result(InvokeActionResult.FAILED);
            return;
        }
        sendActionAnalytics(foundAction, notification, attributes);
        if (foundAction instanceof PblNotificationDismissAction) {
            Trace.debug(TAG, "PblNotificationDismissAction; dismissing...");
            ((PblNotificationDismissAction) foundAction).dismiss();
            callback.result(InvokeActionResult.DISMISSED);
            return;
        }
        InvokeActionResult result = InvokeActionResult.FAILED;
        if (foundAction instanceof PblNotificationAndroidAction) {
            Trace.debug(TAG, "PblNotificationAndroidAction; sending Intent");
            if (((PblNotificationAndroidAction) foundAction).sendAction()) {
                result = foundAction instanceof PblNotificationOpenOnPhoneAction ? InvokeActionResult.OPENED_ON_PHONE : InvokeActionResult.DEFAULT_ACTION;
            }
        } else if (foundAction instanceof PblNotificationGmailAction) {
            Trace.debug(TAG, "PblNotificationGmailAction; invoking");
            ((PblNotificationGmailAction) foundAction).invoke(callback);
            return;
        } else if (foundAction instanceof PblNotificationReplyAction) {
            Trace.debug(TAG, "PblNotificationReplyAction; sending Intent");
            PblNotificationReplyAction androidAction = (PblNotificationReplyAction) foundAction;
            if (attributes == null) {
                Trace.error(TAG, "Tried to send reply, but attributes are null");
                callback.result(InvokeActionResult.FAILED);
                return;
            }
            if (attributes.containsKey(Integer.valueOf(1))) {
                String reply = (String) attributes.get(Integer.valueOf(1));
                Trace.debug(TAG, "Sending reply: " + reply);
                androidAction.sendReply(reply, context, callback);
                return;
            }
            Trace.error(TAG, "Tried to send reply, but attributes do not contain title");
            callback.result(InvokeActionResult.FAILED);
            return;
        } else {
            Trace.debug(TAG, "invokeAction: not valid action type found for ID: " + actionId);
        }
        callback.result(result);
    }

    public boolean handleNotificationNack(UnsignedInteger notificationId) {
        this.mNotificationActions.remove(notificationId);
        return true;
    }

    public static void sendActionAnalytics(PblNotificationAction action, PblNotificationModel.Record notification, Map<Integer, String> attributes) {
        String appName;
        Map<String, Object> dataFields = new HashMap();
        dataFields.put("action_type", action.getClass().getSimpleName());
        dataFields.put("action_title", action.getTitle());
        dataFields.put("action_attributes", attributes.toString());
        dataFields.put("package_name", notification == null ? "unknown" : notification.androidPackageName);
        Record appRecord = null;
        if (notification != null) {
            appRecord = PblAndroidAppModel.getAppRecord(notification.androidPackageName, PebbleApplication.getAppContext().getContentResolver());
        }
        if (appRecord == null) {
            appName = "unknown";
        } else {
            appName = appRecord.appName;
        }
        dataFields.put("app_name", appName);
        MobileAppBehavior.logNotificationActionInvoked(dataFields);
    }
}
